package com.lgCore.client;

import com.lgCore.clientHandler.RpcMsgHandler;
import com.lgCore.clientHandler.LoginResponceHandler;
import com.lgCore.protoModel.ProtoMsg;
import com.lgCore.queue.ClientResultQueue;
import com.lgCore.rpc.common.codec.CommonRpcDecoderHandler;
import com.lgCore.rpc.common.codec.CommonRpcEncoderHandler;
import com.lgCore.rpc.common.codec.RpcProtobufDecoder;
import com.lgCore.rpc.common.codec.RpcProtobufEncoder;
import com.lgCore.util.ProtoByteUtil;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.Attribute;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;


public class NettyClientBootstrap {
    Logger log = LoggerFactory.getLogger(NettyClientBootstrap.class);
    private int port;
    private String host;
    private Channel channel;
    private static final EventExecutorGroup group = new DefaultEventExecutorGroup(20);

    public NettyClientBootstrap(int port, String host) throws InterruptedException {
        this.port = port;
        this.host = host;
        start();
    }

    public Channel getChannel() {
        return channel;
    }

    private void start() throws InterruptedException {
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.channel(NioSocketChannel.class);
        bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
        bootstrap.group(eventLoopGroup);
        bootstrap.remoteAddress(host, port);
        bootstrap.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {
                socketChannel.pipeline().addLast(new IdleStateHandler(20, 10, 0));

//                socketChannel.pipeline().addLast(new RpcProtobufEncoder());
//                socketChannel.pipeline().addLast(new RpcProtobufDecoder());
//                socketChannel.pipeline().addLast("deCoder", new RpcProtobufDecoder());
//                socketChannel.pipeline().addLast("enCoder", new RpcProtobufEncoder());
                socketChannel.pipeline().addLast("decoder", new CommonRpcDecoderHandler());
                socketChannel.pipeline().addLast("encoder", new CommonRpcEncoderHandler());
//                socketChannel.pipeline().addLast(new ProtobufVarint32FrameDecoder());//添加protobuff解码器
//                socketChannel.pipeline().addLast(new ProtobufDecoder(ProtoMsg.Message.getDefaultInstance()));//添加protobuff对应类解码器
//                socketChannel.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());//protobuf的编码器 和上面对对应
//                socketChannel.pipeline().addLast(new ProtobufEncoder());//protobuf的编码器

//                socketChannel.pipeline().addLast(new ObjectEncoder());
//                socketChannel.pipeline().addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
                socketChannel.pipeline().addLast("loginResponseHandler",new LoginResponceHandler());
                socketChannel.pipeline().addLast(new RpcMsgHandler());
            }
        });
        ChannelFuture future = bootstrap.connect(host, port).sync();
        if (future.isSuccess()) {
            channel =future.channel();
            System.out.println("connect server  成功---------");
            //发送登录消息
            ProtoMsg.Message.Builder message = ProtoMsg.Message.newBuilder();
            //登录请求
            ProtoMsg.LoginRequest.Builder loginRequestBuilder = ProtoMsg.LoginRequest.newBuilder();
            loginRequestBuilder.setUserName("ligang");
            loginRequestBuilder.setPassword("ligang");
            loginRequestBuilder.setType(ProtoMsg.HeadType.LOGIN_REQUEST);
            message.setLoginRequest(loginRequestBuilder);
            channel.writeAndFlush(ProtoByteUtil.protoToByte(message));
            Thread.sleep(500L);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        //Constants.setClientId("101");
        NettyClientBootstrap bootstrap = new NettyClientBootstrap(9999, "127.0.0.1");

        ProtoMsg.Message.Builder message = ProtoMsg.Message.newBuilder();
        //登录请求
        ProtoMsg.LoginRequest.Builder loginRequestBuilder = ProtoMsg.LoginRequest.newBuilder();
        loginRequestBuilder.setClientId("唯一客户id");
        loginRequestBuilder.setUserName("ligang");
        loginRequestBuilder.setPassword("2222");
        loginRequestBuilder.setType(ProtoMsg.HeadType.LOGIN_REQUEST);
        message.setLoginRequest(loginRequestBuilder);
        bootstrap.channel.writeAndFlush(ProtoByteUtil.protoToByte(message));
//        bootstrap.socketChannel.writeAndFlush("3333333333333333333");
//        while (true){
//            TimeUnit.SECONDS.sleep(15);
//	           /* AskMsg askMsg=new AskMsg();
//	            askMsg.setClientId(Constants.getClientId());
//	            AskParams askParams=new AskParams();
//	            askParams.setAuth("authToken");
//	            askMsg.setParams(askParams);
//	            bootstrap.socketChannel.writeAndFlush(askMsg);*/
//
//	          /*  PingMsg pingMsg = new PingMsg();
//	            pingMsg.setClientId(Constants.getClientId());
//	            System.out.println("send ping from client----------"+new Date());
//
//	            bootstrap.socketChannel.writeAndFlush(pingMsg);*/
//
//        }
    }
}
